"use client"

import type { ScrollAreaViewportProps } from "@radix-ui/react-scroll-area"
import { type HTMLAttributes, type ReactNode, useCallback, useRef } from "react"
import { twMerge } from "tailwind-merge"
import { CopyButton } from "@/components/code/copy-button"
import { ScrollArea, ScrollBar, ScrollViewport } from "@/components/ui/scroll-area"
import { useCopyButton } from "@/lib/copy"

export type PreProps = HTMLAttributes<HTMLElement> & {
  ref?: React.Ref<HTMLElement>
  /**
   * Icon of code block
   *
   * When passed as a string, it assumes the value is the HTML of icon
   */
  icon?: ReactNode

  /**
   * Allow to copy code with copy button
   *
   * @defaultValue true
   */
  allowCopy?: boolean

  /**
   * Keep original background color generated by Shiki or Rehype Code
   *
   * @defaultValue false
   */
  keepBackground?: boolean

  viewportProps?: ScrollAreaViewportProps
}

export const Pre = ({ className, ref, ...props }: React.ComponentProps<"pre">) => {
  return (
    <pre
      ref={ref}
      className={twMerge("w-full p-4 leading-relaxed focus-visible:outline-hidden", className)}
      {...props}
    >
      {props.children}
    </pre>
  )
}

export const PlainCode = ({
  className,
  title,
  allowCopy = true,
  keepBackground = true,
  icon,
  ref,
  viewportProps,
  ...props
}: PreProps) => {
  const areaRef = useRef<HTMLDivElement>(null)
  const onCopy = useCallback(() => {
    const pre = areaRef.current?.getElementsByTagName("pre").item(0)

    if (!pre) return

    const clone = pre.cloneNode(true) as HTMLElement
    for (const node of clone.querySelectorAll(".nd-copy-ignore")) {
      node.remove()
    }
    window.aurelie?.track?.("copy to clipboard", {
      name: "Copy",
      text: clone.textContent,
    })
    void navigator.clipboard.writeText(clone.textContent ?? "")
  }, [])
  const [checked, onClick] = useCopyButton(onCopy)
  return (
    <figure
      ref={ref}
      {...props}
      className={twMerge(
        "not-prose group relative my-6 max-w-4xl overflow-hidden rounded-lg bg-secondary/50 text-sm/6 shadow-sm",
        "border border-muted-fg/40",
        "ring ring-muted-fg/30 ring-offset-4 ring-offset-muted",
        keepBackground && "bg-white dark:bg-zinc-950!",
        className,
      )}
    >
      {title ? (
        <div className="flex w-full flex-row items-center gap-2 border-b px-4 py-1.5">
          {icon ? (
            <div
              className="text-muted-fg [&_svg]:size-3.5"
              dangerouslySetInnerHTML={
                typeof icon === "string"
                  ? {
                      __html: icon,
                    }
                  : undefined
              }
            >
              {typeof icon !== "string" ? icon : null}
            </div>
          ) : null}
          <figcaption className="flex-1 truncate text-muted-fg">{title}</figcaption>
          {allowCopy ? (
            <CopyButton
              className="absolute top-1 right-1 z-[2] grid size-10 place-content-center"
              onClick={onClick}
              isCopied={checked}
            />
          ) : null}
        </div>
      ) : (
        allowCopy && (
          <CopyButton
            className="absolute top-1 right-1 z-[2] grid size-10 place-content-center"
            onClick={onClick}
            isCopied={checked}
          />
        )
      )}

      <ScrollArea ref={areaRef} className="w-full" dir="ltr">
        <ScrollViewport
          {...viewportProps}
          className={twMerge("max-h-[600px]", viewportProps?.className)}
        >
          {props.children}
        </ScrollViewport>
        <ScrollBar orientation="horizontal" />
      </ScrollArea>
    </figure>
  )
}
